<html>
<head><meta charset="utf-8"><title>Finding a ra_hir::Trait by name/path · t-compiler/rust-analyzer · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/index.html">t-compiler/rust-analyzer</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Finding.20a.20ra_hir.3A.3ATrait.20by.20name.2Fpath.html">Finding a ra_hir::Trait by name/path</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="192432249"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Finding%20a%20ra_hir%3A%3ATrait%20by%20name/path/near/192432249" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Hall <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Finding.20a.20ra_hir.3A.3ATrait.20by.20name.2Fpath.html#192432249">(Mar 31 2020 at 18:42)</a>:</h4>
<p>Hey all, I'm looking into <a href="https://github.com/rust-analyzer/rust-analyzer/issues/3766" title="https://github.com/rust-analyzer/rust-analyzer/issues/3766">https://github.com/rust-analyzer/rust-analyzer/issues/3766</a>. I've got a basic version working that creates a Fom impl for the variant your cursor is over iff it's a tuple variant with one element. I thought it best to also disallow the assist if there's already a From impl for the enum with the matching type. Checking for the type is straight forward:</p>
<div class="codehilite"><pre><span></span><span class="kd">let</span><span class="w"> </span><span class="n">e</span>: <span class="nc">hir</span>::<span class="n">Enum</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sema</span><span class="p">.</span><span class="n">to_def</span><span class="p">(</span><span class="o">&amp;</span><span class="n">variant</span><span class="p">.</span><span class="n">parent_enum</span><span class="p">())</span><span class="o">?</span><span class="p">;</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">e_ty</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="n">ty</span><span class="p">(</span><span class="n">sema</span><span class="p">.</span><span class="n">db</span><span class="p">);</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">impls</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ImplDef</span>::<span class="n">all_in_crate</span><span class="p">(</span><span class="n">sema</span><span class="p">.</span><span class="n">db</span><span class="p">,</span><span class="w"> </span><span class="n">krate</span><span class="p">).</span><span class="n">iter</span><span class="p">().</span><span class="n">filter</span><span class="p">(</span><span class="o">|</span><span class="n">i</span><span class="o">|</span><span class="w"> </span><span class="n">i</span><span class="p">.</span><span class="n">target_ty</span><span class="p">(</span><span class="n">sema</span><span class="p">.</span><span class="n">db</span><span class="p">)</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">e_ty</span><span class="p">);</span><span class="w"></span>
</pre></div>


<p>I'm a bit more stuck with matching the trait up. I tried a couple of things but to no avail:</p>
<ul>
<li>I see there's a <code>ImplDef::target_trait</code> method but that gives a <code>TypeRef</code>. There doesn't seem to be much I can do with a <code>TypeRef</code> looking at the API docs. I tried using similar logic to target_ty to resolve it to an actual <code>Type</code> but it couldn't find it. </li>
<li>I tried to build my own <code>ast::Path</code> and then use <code>Semantics::resolve_path</code> on that but it (understandably) doesn't find the path as the node isn't derived from the instance of semantics</li>
<li>I looked at the auto_import assist as I thought that could help. It uses <code>ImportsLocator</code> which seems to take a string to search for and it finds <code>ModuleDef</code>s (which could be a trait) which match. Although <code>From</code> should be in scope I thought this may turn something up, sadly there are no results at all. I note that the tests of auto_import define all the modules they import from, so perhaps this is expected?</li>
</ul>
<p>Any pointers would be appreciated :)</p>



<a name="192433228"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Finding%20a%20ra_hir%3A%3ATrait%20by%20name/path/near/192433228" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Finding.20a.20ra_hir.3A.3ATrait.20by.20name.2Fpath.html#192433228">(Mar 31 2020 at 18:50)</a>:</h4>
<blockquote>
<p>Although From should be in scope I thought this may turn something up, sadly there are no results at all. I note that the tests of auto_import define all the modules they import from, so perhaps this is expected?</p>
</blockquote>
<p>yes, unit tests only have what you define, they don't have std.</p>
<p>ImportsLocator is probably not the right thing to use here though. I think you should be able to build a HIR <code>Path</code> to <code>::core::convert::From</code> and resolve that using <code>semantics.scope(..).resolve_hir_path()</code> to get the trait</p>



<a name="192433537"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Finding%20a%20ra_hir%3A%3ATrait%20by%20name/path/near/192433537" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Finding.20a.20ra_hir.3A.3ATrait.20by.20name.2Fpath.html#192433537">(Mar 31 2020 at 18:53)</a>:</h4>
<p><code>ImplDef</code> needs a method to get the resolved implemented trait; the way to get that is <code>db.impl_trait(impl_id).map(|it| it.value.trait_)</code></p>



<a name="192433810"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Finding%20a%20ra_hir%3A%3ATrait%20by%20name/path/near/192433810" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Florian Diebold <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Finding.20a.20ra_hir.3A.3ATrait.20by.20name.2Fpath.html#192433810">(Mar 31 2020 at 18:55)</a>:</h4>
<p>instead of going through impls yourself, you could also use the trait solver. that would be the 'proper' way, but needs some more API plumbing... there's actually a special case implemented as <code>Type::impls_future</code></p>



<a name="192440988"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/Finding%20a%20ra_hir%3A%3ATrait%20by%20name/path/near/192440988" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Hall <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/Finding.20a.20ra_hir.3A.3ATrait.20by.20name.2Fpath.html#192440988">(Mar 31 2020 at 19:52)</a>:</h4>
<p>Interesting, thanks. I'll give those ideas ago and see if I can get either the naiive or the proper way working :)</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>